home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / procssng / ccs / ccs-11tl.lha / lbl / sun / jpeg / lib / strmjpeg.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-04-30  |  11.2 KB  |  472 lines

  1. /*
  2. %    STReaM_JPEG_READ_WRITE . C
  3. %
  4. %    Copyright (c)    Lawrence Berkeley Labroatory
  5. %
  6. % AUTHOR:     Jin Guojun - LBL, Image Technology Group    1992
  7. */
  8.  
  9. #ifdef    STREAM_IMAGE
  10. #include "jinclude.h"
  11. #ifdef INCLUDES_ARE_ANSI
  12. #include <stdlib.h>        /* to declare exit() */
  13. #endif
  14. #include <ctype.h>        /* to declare tolower() */
  15. #ifdef NEED_SIGNAL_CATCHER
  16. #include <signal.h>        /* to declare signal() */
  17. #endif
  18.  
  19. #ifndef EXIT_FAILURE        /* define exit() codes if not provided */
  20. #define EXIT_FAILURE  1
  21. #endif
  22. #ifndef EXIT_SUCCESS
  23. #ifdef VMS
  24. #define EXIT_SUCCESS  1
  25. #else
  26. #define EXIT_SUCCESS  0
  27. #endif
  28. #endif
  29.  
  30.  
  31. #include "jversion.h"        /* for version message */
  32. #include "hipl_format.h"
  33.  
  34.  
  35. /*
  36.  * This routine determines what format the input file is,
  37.  * and selects the appropriate input-reading module.
  38.  *
  39.  * To determine which family of input formats the file belongs to,
  40.  * we may look only at the first byte of the file, since C does not
  41.  * guarantee that more than one character can be pushed back with ungetc.
  42.  * Looking at additional bytes would require one of these approaches:
  43.  */
  44.  
  45. extern int header_start;
  46.  
  47. int    should_be;
  48. LOCAL int    input_row_pos;
  49. U_IMAGE    uimg;    /* must be global for ld overplacing it.
  50.         If any program, which doesn't use a global uimg, has to use
  51.         get_jpeg_uimg() and set_jpeg_uimg() to exchange its own img
  52.         context with this uimg structure.    */
  53.  
  54. void
  55. get_jpeg_uimg(U_IMAGE *img)
  56. {
  57.     *img = uimg;
  58. }
  59.  
  60. void
  61. set_jpeg_uimg(U_IMAGE *img)
  62. {
  63.     uimg = *img;
  64. }
  65.  
  66.  
  67. METHODDEF void
  68. input_init(compress_info_ptr cinfo)
  69. {
  70.     register U_IMAGE *img = cinfo->img;
  71. /*    (*img->header_handle)(HEADER_READ, img, 0, 0, 0);    */
  72.     cinfo->image_width = img->width;
  73.     cinfo->image_height = img->height;
  74.     cinfo->data_precision = 8;
  75.     switch (img->color_form) {
  76.     case CFM_SGF:
  77.     cinfo->in_color_space = CS_GRAYSCALE;
  78.     cinfo->input_components = 1;
  79.     break;
  80.     case CFM_ILL:
  81.     default:
  82.     cinfo->in_color_space = CS_RGB;
  83.     cinfo->input_components = 3;
  84.     }
  85.  
  86. }
  87.  
  88.  
  89. METHODDEF void
  90. get_input_row(compress_info_ptr cinfo, JSAMPARRAY pixel_row)
  91. {
  92. register U_IMAGE*    img = cinfo->img;
  93. register int    col = img->width;
  94. register JSAMPROW    pr = pixel_row[0], pg = pixel_row[1], pb = pixel_row[2];
  95. register byte    *p = (byte*) img->src + input_row_pos * img->dpy_channels * col;
  96.     switch (img->color_form) {
  97.     case CFM_SCF:
  98.     while (col--) {
  99.         register int c = *p++;
  100.         *pr++ = reg_cmap[0][c];
  101.         *pg++ = reg_cmap[1][c];
  102.         *pb++ = reg_cmap[2][c];
  103.     }
  104.     break;
  105.     case CFM_SEPLANE:
  106.     mesg("warning -- not ready\n");
  107.     case CFM_ILC:
  108.     snf_to_rle(pr, p, col, 3, NULL); /* ? */
  109.     break;
  110.     case CFM_ILL:
  111.     if (img->in_color == CFM_SEPLANE)    {
  112.         p = (byte*) img->src + input_row_pos * col;
  113.         memcpy(pb, p + (col * img->height << 1), col);
  114.         memcpy(pb, p + col * img->height, col);
  115.     } else    {
  116.         memcpy(pb, (char*)p + (col << 1), col);
  117.         memcpy(pg, (char*)p + col, col);
  118.     }
  119.     case CFM_SGF:
  120.     memcpy(pr, (char*)p, col);
  121.     break;
  122.     default:
  123.     prgmerr('f', "strange color form %d", img->color_form);
  124.     }
  125.     input_row_pos++;
  126. }
  127.  
  128. METHODDEF void
  129. input_term(compress_info_ptr cinfo, int term)
  130. {
  131.     if (term)    free(cinfo->img->src);
  132.     else    input_row_pos = 0;
  133. }
  134.  
  135. void
  136. select_file_type(compress_info_ptr cinfo)
  137. {
  138.     cinfo->methods->input_init = input_init;
  139.     cinfo->methods->get_input_row = get_input_row;
  140.     cinfo->methods->input_term = input_term;
  141. }
  142.  
  143.  
  144. /*
  145.  * This routine gets control after the input file header has been read.
  146.  * It must determine what output JPEG file format is to be written,
  147.  * and make any other compression parameter changes that are desirable.
  148.  */
  149.  
  150. METHODDEF void
  151. c_ui_method_selection(compress_info_ptr cinfo)
  152. {
  153.     /* If the input is gray scale, generate a monochrome JPEG file. */
  154.     if (cinfo->in_color_space == CS_GRAYSCALE) {
  155.     j_monochrome_default(cinfo);
  156.     }
  157.     /* For now, always select JFIF output format. */
  158. #ifdef JFIF_SUPPORTED
  159.     jselwjfif(cinfo);
  160. #else
  161.     You shoulda defined JFIF_SUPPORTED.    /* deliberate syntax error */
  162. #endif
  163. }
  164.  
  165.  
  166. /*
  167.  * Signal catcher to ensure that temporary files are removed before aborting.
  168.  * NB: for Amiga Manx C this is actually a global routine named _abort();
  169.  * see -Dsignal_catcher=_abort in CFLAGS.  Talk about bogus...
  170.  */
  171.  
  172. #ifdef NEED_SIGNAL_CATCHER
  173.  
  174. static external_methods_ptr emethods;    /* for access to free_all */
  175.  
  176. GLOBAL void
  177. signal_catcher(int signum)
  178. {
  179.     if (emethods != NULL) {
  180.     emethods->trace_level = 0;    /* turn off trace output */
  181.     (*emethods->free_all) ();    /* clean up memory allocation & temp
  182.                      * files */
  183.     }
  184.     exit(EXIT_FAILURE);
  185. }
  186.  
  187. #endif
  188.  
  189.  
  190. /*
  191.  * The entry program.
  192.  */
  193.  
  194. LOCAL struct Compress_info_struct cinfo;
  195. LOCAL struct Compress_methods_struct c_methods;
  196.  
  197. jpeg_uimg_init(FILE *fp, int itype, int rw, int color)
  198. {    /* only initial once!    */
  199.     if (!rw && uimg.IN_FP == fp || rw && uimg.OUT_FP == fp)    return;
  200.     uimg.color_dpy = color;
  201.     format_init(&uimg, IMAGE_INIT_TYPE, itype, JPEG, "sjpeg", "N25-2");
  202.     if (fp)    if (rw)    uimg.OUT_FP = fp;
  203.         else    uimg.IN_FP = fp;
  204.     init_readpipe(&uimg);
  205. }
  206.  
  207. hjpeg_color(struct header *hd)
  208. {
  209.     memcpy(&hhd, hd, sizeof(*hd));
  210. #ifdef    _DEBUG_
  211.     hips_header_handle(HEADER_FROM, &uimg, hd);
  212. #else
  213.     hips_header_to_jpeg(HEADER_FROM, &uimg, hd);
  214. #endif
  215.     return    isColorImage(uimg.in_color);
  216. }
  217.  
  218. GLOBAL
  219. hhjpeg_winit(FILE * hfp, struct header * hhdp, int qfactor, int color_flag)
  220. {
  221.     jpeg_uimg_init(hfp, RLE, True, color_flag);
  222.     uimg.color_dpy = color_flag;
  223.     cinfo.img = &uimg;
  224. #ifdef    _DEBUG_
  225.     hips_header_handle(HEADER_FROM, &uimg, hhdp);
  226. #else
  227.     hips_header_to_jpeg(HEADER_FROM, &uimg, hhdp);
  228. #endif
  229.     if (color_flag | isColorImage(uimg.in_color))    {
  230.         uimg.dpy_channels = 3;
  231.         uimg.color_form = CFM_ILL;
  232.     }
  233.  
  234.     uimg.src = uimg.dest = hhdp->image;
  235.     if (!uimg.dpy_channels)    uimg.dpy_channels = uimg.channels;
  236.  
  237.     /* Set up links to method structures. */
  238.     cinfo.methods = &c_methods;
  239.     cinfo.emethods = &e_methods;
  240.  
  241.     /* Install, but don't yet enable signal catcher. */
  242. #ifdef NEED_SIGNAL_CATCHER
  243.     emethods = NULL;
  244.     signal(SIGINT, signal_catcher);
  245. #ifdef SIGTERM            /* not all systems have SIGTERM */
  246.     signal(SIGTERM, signal_catcher);
  247. #endif
  248. #endif
  249.  
  250.     /* (Re-)initialize the system-dependent error and memory managers. */
  251.     jselerror(cinfo.emethods);    /* error/trace message routines */
  252.     jselmemmgr(cinfo.emethods);    /* memory allocation routines */
  253.     cinfo.methods->c_ui_method_selection = c_ui_method_selection;
  254.  
  255.     /* Now OK to enable signal catcher. */
  256. #ifdef NEED_SIGNAL_CATCHER
  257.     emethods = cinfo.emethods;
  258. #endif
  259.  
  260.     /* Set up default JPEG parameters. */
  261.     j_c_defaults(&cinfo, qfactor, FALSE);    /* default quality level = 75 */
  262.  
  263.     cinfo.output_file = uimg.OUT_FP = hfp;
  264.  
  265.     cinfo.input_file = uimg.IN_FP ? uimg.IN_FP : stdin;
  266.  
  267.     /* Figure out the input file format, and set up to read it. */
  268.     select_file_type(&cinfo);
  269.  
  270. #ifdef PROGRESS_REPORT
  271.     /* Start up progress display, unless trace output is on */
  272.     if (e_methods.trace_level == 0)
  273.     c_methods.progress_monitor = progress_monitor;
  274. #endif
  275.     cinfo.comp_info[0].h_samp_factor = 2;
  276.     cinfo.comp_info[0].v_samp_factor = 1;
  277.     init_jpeg_header(&cinfo);    /* Must be last line here    */
  278. }
  279.  
  280. stream_jpeg_read_image(void *buf, struct header *hdp, int fn)
  281. {
  282.     uimg.src = buf;
  283.     if (get_sinfo(1, 0) == 1)    {
  284.     sframe_header    sf;
  285.         read_stream_header(uimg.IN_FP, hdp, &sf, fn);
  286.         return    stream_jpeg_read_frame(buf, &sf);
  287.     }
  288.     return    (*uimg.std_swif)(FI_LOAD_FILE, &uimg, NULL, 0);
  289. }
  290.  
  291.  
  292. /*    STReaM_JPEG_READ . C
  293. %
  294. */
  295.  
  296. #ifndef DEFAULT_FMT        /* so can override from CFLAGS in Makefile */
  297. #define DEFAULT_FMT    FMT_PPM
  298. #endif
  299.  
  300.  
  301.  
  302. /*
  303.  * The entry program.
  304.  */
  305.  
  306. #ifndef    JPEG_BUFFER_EDGE
  307. #define    JPEG_BUFFER_EDGE    512
  308. #endif
  309. #define    JPEG_IN_BUF_SIZE    JPEG_BUFFER_EDGE * JPEG_BUFFER_EDGE
  310.  
  311. GLOBAL int
  312. stream_jpeg_rinit(FILE * hfp, int qfact /* not used */, int color_flag)
  313. {
  314. extern IMAGE_FORMATS requested_fmt;
  315.  
  316.     jpeg_uimg_init(hfp, RLE, False, color_flag);
  317.     uimg.color_dpy = color_flag;
  318.     uimg.in_form = IFMT_STREAM;
  319.     requested_fmt = FMT_DEFAULT;
  320.  
  321.     /* Start up progress display, unless trace output is on */
  322. #ifdef PROGRESS_REPORT
  323.     if        (e_methods.trace_level == 0)
  324.     dc_methods.progress_monitor = progress_monitor;
  325. #endif
  326.  
  327.     if (jpeg_header_handle(HEADER_READ, &uimg, 0, 1, 0)) {
  328.     return -1;
  329.     } else {
  330.     register int w = uimg.width, h = uimg.height;
  331.     if (w * h > JPEG_IN_BUF_SIZE)
  332.         w = h = JPEG_BUFFER_EDGE;
  333.     verify_buffer_size(&dinfo.input_buffer, w, h, "jsrc");
  334.     }
  335. return 0;
  336. }
  337.  
  338.  
  339. int
  340. stream_write_jpeg_subheader()
  341. {
  342.     (*cinfo.methods->write_scan_header) (&cinfo);
  343.     return(cinfo.img->tmp_offset);
  344. }
  345.  
  346. stream_jpeg_read_frame(void *buf, sframe_header *sf)
  347. {
  348.     dinfo.img->tmp_offset = sf->size;
  349.     should_be = sf->size + ftell(dinfo.input_file);
  350.     uimg.src = buf;
  351. return    read_next_jpeg_frame(&dinfo);
  352. }
  353.  
  354. stream_jpeg_read_term()
  355. {
  356.     close_jpeg_read(&dinfo);
  357. }
  358.  
  359. stream_jpeg_write_frame(void *buf, sframe_header * sf)
  360. {
  361.     uimg.dest = uimg.src = buf;
  362.     uimg.o_form = IFMT_STREAM;
  363.     write_next_jpeg_frame(&cinfo);
  364.     sf->size = uimg.tmp_offset;
  365. }
  366.  
  367. stream_jpeg_write_term()
  368. {
  369.     close_jpeg_write(&cinfo);
  370. }
  371.  
  372. write_jpeg_eof(FILE *fp)
  373. {
  374. #ifdef    _DEBUG_
  375. register int    i = ftell(fp);
  376.     fprintf(stderr, "M_EOI is put at %d (%X)\n", i, i);
  377. #endif
  378.    putc(0xff,fp);  
  379.    putc(0xd9,fp);  /* end of image marker (from jrdjiff.c) */
  380. }
  381.  
  382. #ifndef    _DEBUG_
  383. hips_header_to_jpeg(int job, U_IMAGE *img, struct header *hhd)
  384. {
  385. int    hform = hhd->pixel_format;
  386.     img->in_type = HIPS;
  387.     img->cmaplen = 0;
  388.     img->color_form = CFM_SGF;    /* default to gray scale    */
  389.     img->channels = hhd->numcolor;
  390.     if (findparam(hhd, "cmap") != NULLPAR)    {
  391.     VType*    cmapp;
  392.     int    nc;
  393.         getparam(hhd, "cmap", PFBYTE, &nc, &cmapp);
  394.         if (nc % 3 || nc > MaxColors*3)
  395.             prgmerr(0, "strange colormap = %d", nc);
  396.         else    {
  397.             if (reg_cmap[0])
  398.                 free(reg_cmap[0]);
  399.             reg_cmap[0] = cmapp;
  400.             img->cmaplen = (nc /= 3);
  401.             reg_cmap[1] = reg_cmap[0] + nc;
  402.             reg_cmap[2] = reg_cmap[1] + nc;
  403.             img->in_color = img->color_form = CFM_SCF;
  404.         }
  405.     }
  406.     else    if (img->channels==3)    {    /* kludge handle SEPLANE */
  407.             if (hform==IFMT_ILC)    /* PFRGB */
  408.                 img->in_color = CFM_ILC;
  409.             else    img->in_color = CFM_SEPLANE;
  410.         }
  411.         else if (hform==IFMT_ALPHA)
  412.             img->in_color = CFM_ALPHA,
  413.             img->channels = 4;
  414.         else if (hform == IFMT_ILC)
  415.             img->in_color = CFM_ILC,
  416.             img->channels = 3;
  417.         else    img->in_color = CFM_SGF;
  418.  
  419.     /*    should select_color_form here    */
  420.     if ((img->in_color == CFM_SEPLANE) & !img->color_dpy) {
  421.         img->dpy_channels = 1;
  422.         img->color_form = CFM_SGF;
  423.     }
  424.  
  425. #if    defined COMMON_TOOL | defined RLE_IMAGE
  426.     /* not force to stick at 1 channel    */
  427.     if (img->mid_type==RLE && img->cmaplen && !assist)    {
  428.         rle_dflt_hdr.ncmap = img->mono_img = 0;
  429.         if (img->color_form != CFM_SGF)
  430.             img->dpy_channels = img->channels = 3;
  431.     }
  432. #endif
  433.     img->frames = hhd->num_frame / hhd->numcolor;
  434.     img->in_form = hhd->pixel_format;
  435.     img->width = hhd->ocols;
  436.     img->height = hhd->orows;
  437.     img->pxl_in = pxl_size((*hhd));
  438.     if (img->pxl_in == 3)
  439.         img->pxl_in = 1;    /* for PFRGB    */
  440.     if (!img->pxl_in) {
  441.     register int    vsize;
  442.         switch (img->in_form)    {
  443.         case IFMT_VFFT3D:
  444.         case IFMT_VFFT2D:
  445.         case IFMT_VVFFT3D:
  446.             vsize = sizeof(float)<<1;
  447.             break;
  448.         case IFMT_DVFFT3D:
  449.         case IFMT_DVFFT2D:
  450.         case IFMT_DVVFFT3D:
  451.             vsize = sizeof(double)<<1;
  452.             break;
  453.         case IFMT_HIST:
  454.             vsize  = sizeof(int);
  455.             break;
  456.         default:vsize = 1;
  457.             msg("%d: undetermined size", img->in_form);
  458.         }
  459.         img->pxl_in = vsize;
  460.     }
  461.     img->history = hhd->seq_history;
  462.     img->desc = hhd->seq_desc;
  463.     img->sub_img_w = hhd->cols;
  464.     img->sub_img_h = hhd->rows;
  465.     img->sub_img_x = hhd->fcol;
  466.     img->sub_img_y = hhd->frow;
  467.     select_color_form(img, True);
  468. }
  469. #endif
  470. #endif
  471.  
  472.